const
    fs = require('fs'),
    path = require('path'),
    paths = require('./paths'),
    NODE_ENV = process.env.NODE_ENV || 'development'
;
delete require.cache[require.resolve('./paths')];

if(!NODE_ENV) {
    throw new Error('The NODE_ENV variable is required but was not specified');
}

const 
    dotenvFiles = [
        `${paths.dotenv}.${NODE_ENV}.local`,
        `${paths.dotenv}.${NODE_ENV}`,
        NODE_ENV !== 'test' && `${paths.dotenv}.local`,
        paths.dotenv
    ].filter(Boolean)
;
dotenvFiles.forEach(dotenvFile => {
    if(fs.existsSync(dotenvFile)) {
        require('dotenv').config({ path: dotenvFile });
    }
});

const 
    appDirectory = fs.realpathSync(process.cwd())
;
process.env.NODE_PATH = (process.env.NODE_PATH || '')
    .split(path.delimiter)
    .filter(folder => folder && !path.isAbsolute(folder))
    .map(folder => path.resolve(appDirectory, folder))
    .join(path.delimiter)
;

const 
    REACT_APP = /^REACT_APP_/i,
    getClientEnvironment = function (publicUrl) {
        const 
            raw = Object.keys(process.env)
                .filter(key => REACT_APP.test(key))
                .reduce((env, key) => {
                    env[key] = process.env[key];
                    return env;
                }, {
                    NODE_ENV: process.env.NODE_ENV || 'development',
                    PUBLIC_URL: publicUrl
                }),
            stringified = {
                'process.env': Object.keys(raw).reduce((env, key) => {
                    env[key] = JSON.stringify(raw[key]);
                    return env;
                }, {})
            }
        ;

        return { raw, stringified };
    }
;
module.exports = getClientEnvironment;